package com.katesoft.scale4j.demo.services;

import static com.katesoft.scale4j.persistent.utils.DataAccessUtility.fetchFirstRowOrNull;

import java.io.BufferedReader;
import java.io.StringReader;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.web.client.RestTemplate;

import com.katesoft.scale4j.demo.domain.Currency;
import com.katesoft.scale4j.demo.domain.ExchangeRate;
import com.katesoft.scale4j.log.LogFactory;
import com.katesoft.scale4j.log.Logger;
import com.katesoft.scale4j.persistent.client.LocalHibernateTemplate;

public class CurrencyExchangeRatesTasklet implements Tasklet {
   private final Logger logger = LogFactory.getLogger(getClass());
   private final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
   private final RestTemplate template = new RestTemplate();
   private LocalHibernateTemplate hibernateTemplate;

   @SuppressWarnings({ "unchecked" })
   @Override
   public RepeatStatus execute(@SuppressWarnings("unused") StepContribution contribution,
            final ChunkContext chunkContext) {
      ExecutionContext context = chunkContext.getStepContext().getStepExecution().getJobExecution()
               .getExecutionContext();
      String date = context.containsKey("date") ? context.getString("date") : sf.format(new Date());
      List<Currency> currencyList = hibernateTemplate.loadAll(Currency.class);
      for (Currency currency : currencyList) {
         logger.info(
                  "%s ***********************************************************************************************",
                  currency.getCode());
         try {
            String s = template.getForObject(
                     "http://currencies.apps.grandtrunk.net/getrate/{date}/{fromcode}/{tocode}",
                     String.class, date, "USD", currency.getCode());
            logger.info("got %s for values = %s", s,
                     Arrays.toString(new String[] { date, "USD", currency.getCode() }));
            BufferedReader reader = new BufferedReader(new StringReader(s));
            try {
               String next;
               while ((next = reader.readLine()) != null) {
                  ExchangeRate exchangeRate = new ExchangeRate();
                  exchangeRate.setCurrency(currency);
                  exchangeRate.setRate(new BigDecimal(next));
                  exchangeRate.setActualDate(sf.parse(date));
                  ExchangeRate existingRate = (ExchangeRate) fetchFirstRowOrNull(hibernateTemplate
                           .findByNamedQuery("exchange_rate.find_by_code", currency));
                  if (existingRate != null) {
                     existingRate.setRate(exchangeRate.getRate());
                     existingRate.setActualDate(sf.parse(date));
                     hibernateTemplate.update(existingRate);
                  } else {
                     hibernateTemplate.save(exchangeRate);
                  }
                  hibernateTemplate.flush();
               }
            } finally {
               reader.close();
            }
         } catch (Exception e) {
            logger.warn(e);
         }
      }
      hibernateTemplate.flush();
      return RepeatStatus.FINISHED;
   }

   @Autowired
   @Required
   public void setHibernateTemplate(LocalHibernateTemplate hibernateTemplate) {
      this.hibernateTemplate = hibernateTemplate;
   }
}
